﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace CardDataWCFService
{
    public static class GameLogic
    {

        /// <summary>
        /// Adds a new player.
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        public static Player AddPlayer(Player player)
        {
            using (CardLINQDataContext context = new CardLINQDataContext())
            {
                context.Players.InsertOnSubmit(player);
                context.SubmitChanges();

                return player;
            }
        }

        public static PlayerCard GetPlayerCardByRFID(String CardRFID)
        {
            using (CardLINQDataContext context = new CardLINQDataContext())
            {
                var playercards = from playercard in context.PlayerCards
                                  where (playercard.CardRFID.Equals(CardRFID))
                                  select playercard;
                return playercards.First(); //InvalidOperationException means the card has not been registered.
            }
        }

        public static PlayerCard GetPlayerCardByCardID(int CardID)
        {
            using (CardLINQDataContext context = new CardLINQDataContext())
            {
                var playercards = from playercard in context.PlayerCards
                                  where (playercard.CardID.Equals(CardID))
                                  select playercard;

                return playercards.First();
            }
        }

        public static bool DeleteAllPlayers()
        {
            using (CardLINQDataContext context = new CardLINQDataContext())
            {
                var players = from player in context.Players
                              select player;

                context.Players.DeleteAllOnSubmit(players);
            }
            return true;
        }

        /// <summary>
        /// Gets a list of all the players in the game.
        /// </summary>
        /// <returns>A list of all the players.</returns>
        public static List<Player> GetPlayers()
        {
            using (CardLINQDataContext context = new CardLINQDataContext())
            {
                var players = from player in context.Players
                              select player;
                return players.ToList();
            }
        }

        /// <summary>
        /// Deletes a player by name
        /// </summary>
        /// <param name="PlayerName"></param>
        /// <returns></returns>
        public static bool DeletePlayerByName(Player playerToDelete)
        {
            using (CardLINQDataContext context = new CardLINQDataContext())
            {
                var players = from player in context.Players
                              where player.PlayerName.ToLower().Equals(playerToDelete.PlayerName.ToLower())
                              select player;

                context.Players.DeleteAllOnSubmit(players);

                context.SubmitChanges();
            }
            return true;
        }

        /// <summary>
        /// Deletes a player by name
        /// </summary>
        /// <param name="PlayerName"></param>
        /// <returns></returns>
        public static bool DeletePlayerByID(Player playerToDelete)
        {
            using (CardLINQDataContext context = new CardLINQDataContext())
            {
                var players = from player in context.Players
                              where player.PlayerID == playerToDelete.PlayerID
                              select player;

                context.Players.DeleteAllOnSubmit(players);

                context.SubmitChanges();
            }
            return true;
        }

        /// <summary>
        /// Returns the game to its original state.
        /// </summary>
        /// <returns></returns>
        public static bool ShuffleDeck()
        {
            using (CardLINQDataContext context = new CardLINQDataContext())
            {
                //Reset Held By Table
                var heldbies = from heldby in context.HeldBies
                               select heldby;
                context.HeldBies.DeleteAllOnSubmit(heldbies);
                context.SubmitChanges();

                //Reset Players Table
                var players = from player in context.Players
                              select player;
                if (players.Count() > 0)
                {
                    context.Players.DeleteAllOnSubmit(players);
                }

                context.SubmitChanges();

                //Initialize Players
                Player dealer = new Player();
                dealer.PlayerName = "Dealer";
                AddPlayer(dealer);

                Player np1 = new Player();
                np1.PlayerName = "Player 1";
                AddPlayer(np1);

                Player np2 = new Player();
                np2.PlayerName = "Player 2";
                AddPlayer(np2);

                Player table = new Player();
                table.PlayerName = "Table";
                AddPlayer(table);

                //Reset Cards Table
                var cards = from card in context.Cards
                            select card;

                if (cards.Count() > 0)
                {
                    context.Cards.DeleteAllOnSubmit(cards);
                }
                context.SubmitChanges();

                //Initialize Cards
                List<Card> cardsToAdd = new List<Card>();

                Card kingOfDiamonds = new Card();
                kingOfDiamonds.CardRFID = "0e00ec32bf";
                kingOfDiamonds.Suit = "Diamonds";
                kingOfDiamonds.Type = "King";
                kingOfDiamonds.ImageFileName = "26";
                cardsToAdd.Add(kingOfDiamonds);

                Card sevenOfDiamonds = new Card();
                sevenOfDiamonds.CardRFID = "0b009565f9";
                sevenOfDiamonds.Suit = "Diamonds";
                sevenOfDiamonds.Type = "Seven";
                sevenOfDiamonds.ImageFileName = "20";
                cardsToAdd.Add(sevenOfDiamonds);

                Card aceOfDiamonds = new Card();
                aceOfDiamonds.CardRFID = "0e00b975b2";
                aceOfDiamonds.Suit = "Diamonds";
                aceOfDiamonds.Type = "Ace";
                aceOfDiamonds.ImageFileName = "14";
                cardsToAdd.Add(aceOfDiamonds);

                Card jackOfClubs = new Card();
                jackOfClubs.CardRFID = "0e00ec0afe";
                jackOfClubs.Suit = "Clubs";
                jackOfClubs.Type = "Jack";
                jackOfClubs.ImageFileName = "11";
                cardsToAdd.Add(jackOfClubs);

                Card sixOfHearts = new Card();
                sixOfHearts.CardRFID = "0e00b9344f";
                sixOfHearts.Suit = "Hearts";
                sixOfHearts.Type = "Six";
                sixOfHearts.ImageFileName = "32";
                cardsToAdd.Add(sixOfHearts);

                Card tenOfSpades = new Card();
                tenOfSpades.CardRFID = "0e007100a2";
                tenOfSpades.Suit = "Spades";
                tenOfSpades.Type = "Ten";
                tenOfSpades.ImageFileName = "49";
                cardsToAdd.Add(tenOfSpades);

                Card aceOfHearts = new Card();
                aceOfHearts.CardRFID = "010445c5a5";
                aceOfHearts.Suit = "Hearts";
                aceOfHearts.Type = "Ace";
                aceOfHearts.ImageFileName = "27";
                cardsToAdd.Add(aceOfHearts);

                Card aceOfSpades = new Card();
                aceOfSpades.CardRFID = "0b00953c31";
                aceOfSpades.Suit = "Spades";
                aceOfSpades.Type = "Ace";
                aceOfSpades.ImageFileName = "40";
                cardsToAdd.Add(aceOfSpades);

                Card eightOfSpades = new Card();
                eightOfSpades.CardRFID = "0f00a9f099";
                eightOfSpades.Suit = "Spades";
                eightOfSpades.Type = "Eight";
                eightOfSpades.ImageFileName = "47";
                cardsToAdd.Add(eightOfSpades);

                Card threeofSpades = new Card();
                threeofSpades.CardRFID = "010445c8e9";
                threeofSpades.Suit = "Spades";
                threeofSpades.Type = "Three";
                threeofSpades.ImageFileName = "42";
                cardsToAdd.Add(threeofSpades);

                context.Cards.InsertAllOnSubmit(cardsToAdd);
                context.SubmitChanges();

                //Initialize HeldBy Table

                foreach (Card card in cardsToAdd)
                {
                    HeldBy hb = new HeldBy();
                    hb.CardID = card.CardID;
                    hb.PlayerID = dealer.PlayerID;
                    context.HeldBies.InsertOnSubmit(hb);
                }

                context.SubmitChanges();
            }
            return true;
        }

        public static List<PlayerCard> GetCardsByPlayerID(Player player)
        {
            using(CardLINQDataContext context = new CardLINQDataContext())
            {
                var playercards = from playercard in context.PlayerCards
                                  where playercard.PlayerID == player.PlayerID
                                  select playercard;
                
                return playercards.ToList();
            }
        }

        public static Dictionary<Player, List<PlayerCard>> GetAllCardsByPlayers()
        {
            Dictionary<Player, List<PlayerCard>> playerCards = new Dictionary<Player, List<PlayerCard>>();
            List<Player> players = GetPlayers();

            foreach (Player player in players)
            {
                playerCards.Add(player, GetCardsByPlayerID(player));
            }

            return playerCards;
        }

        public static PlayerCard TransferCardOwnership(HeldBy heldby)
        {
            using (CardLINQDataContext context = new CardLINQDataContext())
            {
                var heldbies = (from _heldby in context.HeldBies
                                where _heldby.CardID == heldby.CardID
                                select _heldby).Single();

                heldbies.PlayerID = heldby.PlayerID;

                context.SubmitChanges();
                return GameLogic.GetPlayerCardByCardID(heldbies.CardID);
            }
            
        }
    }
}
